<?php

// +-------------------------------------------
// | Name: 星空后台 公共模型
// +-------------------------------------------
// | Version: V5.0
// +-------------------------------------------
// | Author: xkyinzhe <zhonghuaxinxing@sina.cn>
// +-------------------------------------------
// | Time: 2021-04-09 13:44
// +-------------------------------------------
declare(strict_types=1);

namespace app\common\model;

use think\exception\ValidateException;
use think\model;
// 导出执行
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

/**
 * @xk 公共模型
 */
class BaseModel extends Model
{
    /**
     * @xk 查询后操作
     *
     * @method onAfterRead
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:47:40+080
     */
    public static function onAfterRead($data)
    {
        // 查询后：每次执行就查询一条数据
    }

    /**
     * @xk 新增前操作
     *
     * @method onBeforeInsert
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:48:00+080
     */
    public static function onBeforeInsert($data)
    {
        // 新增前：获取的新增数据，还没新增
    }

    /**
     * @xk 新增后操作
     *
     * @method onAfterInsert
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:48:10+080
     */
    public static function onAfterInsert($data)
    {
        // 新增后：获取的新增数据，已经新增数据
    }

    /**
     * @xk 更新前操作
     *
     * @method onBeforeUpdate
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:48:25+080
     */
    public static function onBeforeUpdate($data)
    {
        // 更新前：获取的更新数据，还没更新数据
    }

    /**
     * @xk 更新后操作
     *
     * @method onAfterUpdate
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:48:44+080
     */
    public static function onAfterUpdate($data)
    {
        // 更新后：获取的更新数据，已经更新数据
    }

    /**
     * @xk 写入前操作
     *
     * @method onBeforeWrite
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:48:54+080
     */
    public static function onBeforeWrite($data)
    {
        // 写入前：获取的当前数据，还没新增、更新
    }

    /**
     * @xk 写入后操作
     *
     * @method onAfterWrite
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:49:08+080
     */
    public static function onAfterWrite($data)
    {
        // 写入后：获取的当前数据
    }

    /**
     * @xk 删除前操作
     *
     * @method onBeforeDelete
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:49:21+080
     */
    public static function onBeforeDelete($data)
    {
        // 删除前：获取的删除前数据，还没删除
    }

    /**
     * @xk 删除后操作
     *
     * @method onAfterDelete
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:49:33+080
     */
    public static function onAfterDelete($data)
    {
        // 删除后：获取的删除数据，已经删除
    }

    /**
     * @xk 恢复前操作
     *
     * @method onBeforeRestore
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:49:49+080
     */
    public static function onBeforeRestore($data)
    {
        //恢复前
    }

    /**
     * @xk 恢复后操作
     *
     * @method onAfterRestore
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:50:12+080
     */
    public static function onAfterRestore($data)
    {
        //恢复后
    }

    /**
     * @xk 模型验证
     *
     * @method validate
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-16T11:08:52+080
     */
    public function validate($data, $scene = '')
    {
        $validInstance = app(str_replace('model', 'validate', get_class($this)));
        $res = $validInstance
          ->scene($scene)
          ->check($data);
        if (!$res) {
            throw new ValidateException($validInstance->getError(), -2);
        }
    }

    /**
     * @xk 动态内容修改
     *
     * @method chanageValue
     *
     * @param [type] $data [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-09T13:55:26+080
     */
    public static function chanageValue($data)
    {
        if (!$data) {
            return false;
        }
        $key = isset($data['key']) ? $data['key'] : 'status';
        $value = isset($data['value']) ? $data['value'] : 1;
        $by_key = isset($data['by_key']) ? $data['by_key'] : 'cate_id';
        $res = self::find($by_key)->save([$key => $value]);
        if (!$res) {
            return false;
        }

        return true;
    }

    /**
     * @xk 获取上级族谱
     *
     * @method checkParent
     *
     * @param int    $parent_id     [description]
     * @param string $parent_key    [description]
     * @param string $parent_id_key [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-19T11:27:29+080
     */
    public static function checkParent($parent_id = 0, $parent_key = 'parent_str', $parent_id_key = 'cate_id')
    {
        if ($parent_id <= 0) {
            return '0,';
        }
        $old_parent_str = self::where([$parent_id_key => $parent_id])->value($parent_key);
        if ($old_parent_str) {
            return $old_parent_str.$parent_id.',';
        }

        return '0,'.$parent_id.',';
    }

    /**
     * @xk 执行子内容删除
     *
     * @method destoryChildren
     *
     * @param [type] $parent_id  [description]
     * @param string $search_key [要查询的字段]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-19T11:31:03+080
     */
    public static function destoryChildren($parent_id, $search_key = 'menu_id')
    {
        $new_arr = self::where(['parent_id' => $parent_id])->column($search_key);
        if ($new_arr) {
            self::destroy($new_arr);
        }
    }

    /**
     * @xk 更新族谱
     *
     * @method updateParentStr
     *
     * @param int    $parent_id  [description]
     * @param string $parent_str [description]
     * @param string $key        [description]
     * @param string $search_key [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-19T11:33:35+080
     */
    public static function updateParentStr($parent_id = 0, $parent_str = '0,', $by_key = 'parent_id', $search_key = 'menu_id')
    {
        if ($parent_id <= 0) {
            return true;
        }
        $list = self::where([$by_key => $parent_id])->column($search_key);
        if (!$list) {
            return true;
        }
        foreach ($list as $key => $value) {
            self::find($value)->save(['parent_str' => $parent_str]);
            self::updateParentStr($value, $parent_str.$value.',', $by_key, $search_key);
        }

        return true;
    }

    /**
     * @xk 获取树形列表
     *
     * @method getTreeList
     *
     * @param string $search_key [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-19T13:27:23+080
     */
    public static function getTreeList($search_key = 'menu_id')
    {
        $list = self::select();
        $list_tree = self::getTree($list, $search_key);

        return $list_tree ? $list_tree : '';
    }

    /**
     * @xk 数据树形操作
     *
     * @method getTree
     *
     * @param [type] $dataList   [description]
     * @param [type] $search_key [description]
     * @param int    $pid        [description]
     * @param int    $depth      [description]
     * @param string $prefix     [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-19T13:27:36+080
     */
    public static function getTree($dataList, $search_key, $pid = 0, $depth = 0, $prefix = '|--')
    {
        $resTree = [];
        foreach ($dataList as $key => $val) {
            if ($val['parent_id'] == $pid) {
                $val['depth'] = $depth;
                $val['prefix'] = str_repeat($prefix, $depth);
                unset($dataList[$key]);
                $resTree[] = $val;
                $resTree = array_merge($resTree, self::getTree($dataList, $search_key, $val[$search_key], $depth + 1));
            }
        }

        return $resTree;
    }

    /**
     * @xk 创建字符串
     *
     * @method getCodeNo
     *
     * @param [type] $cp         [description]
     * @param [type] $length     [description]
     * @param [type] $type       [description]
     * @param [type] $search_key [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-27T10:03:02+080
     */
    public static function getCodeNo($cp = 'xk', $length = 12, $type = 1, $search_key = '')
    {
        switch ($type) {
        case '1':
          $numstr = '0123456789';
          break;
        case '2':
          $numstr = 'abcdefghijklmnopqrstuvwxyz';
          break;
        case '3':
          $numstr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
          break;
        case '4':
          $numstr = '0123456789abcdefghijklmnopqrstuvwxyz';
          break;
        case '5':
          $numstr = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
          break;
        case '6':
          $numstr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
          break;
        default:
          $numstr = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
          break;
      }
        $len = strlen($numstr);
        $cdlen = strlen($cp);
        $haslength = $length - $cdlen;
        $randStr = '';
        for ($i = 0; $i < $haslength; ++$i) {
            $randStr .= $numstr[rand(0, $len - 1)];
        }
        $newnum = $cp.$randStr;
        if ('' != $search_key) {
            if (self::checkNum($search_key, $newnum)) {
                return $newnum;
            } else {
                self::getCodeNo($cp, $length, $type, $search_key);
            }
        } else {
            return $newnum;
        }
    }

    /**
     * @xk 核验参数
     *
     * @method checkNum
     *
     * @param [type] $search_key   [description]
     * @param [type] $search_value [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-04-27T10:06:24+080
     */
    public static function checkNum($search_key, $search_value)
    {
        $count = self::where([[$search_key, '=', $search_value]])->count();
        if ($count > 0) {
            return false;
        }

        return true;
    }

    /**
     * @xk 检测标志
     *
     * @method checkSign
     *
     * @param [type] $sign [description]
     * @param int    $i    [description]
     *
     * @return [type] [description]
     * @Author xkyinzhe                <zhonghuaxinxing@sina.cn>
     * @Time   2021-05-28T17:33:53+080
     */
    public static function checkSign($sign, $i = 1)
    {
        $count = self::checkNum('sign', $sign);
        if (!$count) {
            $sign = self::checkSign($sign.$i, $i++);
        }

        return $sign;
    }
    /**
     * @xk 导出成为表格
     *
     * @method export
     * @param  array      $title                     [description]
     * @param  array      $data                      [description]
     * @param  string     $path                      [description]
     * @param  array      $width                     [description]
     * @param  integer    $page                      [description]
     * @return [type]     [description]
     * @Time   2021-09-08
     * @City   青岛
     * @Author xkyinzhe   <zhonghuaxinxing@sina.cn>
     */
    public static function export($title = [], $data = [], $path = '/export', $width = [],$page=0,$export_name='')
    {
        // 获取Spreadsheet对象
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();
            $nowpath = app()->getRootPath().'/public'.$path;
            if (!file_exists($nowpath)) {
                mkdir($nowpath, 0777, true);
            }
          // 表头单元格内容 第一行
          $titCol = 'A';
            foreach ($title as $value) {
                // 单元格内容写入
                $sheet->setCellValue($titCol . '1', $value);
                $titCol++;
            }
            // 设置列宽
            if($width){
                $dataCol = 'A';
                foreach ($width as $key => $value) {
                  $spreadsheet->getActiveSheet()->getColumnDimension($dataCol)->setWidth($value);
                    $dataCol++;
                }
            }
            // 从第二行开始写入数据
            $row = 2;
            foreach ($data as $item) {
                $dataCol = 'A';
                $height = 20;
                foreach ($item as $value) {
                    // 单元格内容写入
                    if((!is_numeric($value)) || (is_numeric($value) && strlen((string)$value) >= 10)){
                      $value = $value."\t";
                    }
                    $sheet->setCellValue($dataCol . $row, $value);
                    $dataCol++;
                }
                // $spreadsheet->getActiveSheet()->getRowDimension($row)->setRowHeight($height);
                $row++;
            }

            $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
            if($page == 0){
                $url = $nowpath.'/'.date('Ymdhis').$export_name.'.xlsx';
                $send_path = $path.'/'.date('Ymdhis').$export_name.'.xlsx';
            }else{
                $url = $nowpath.'/'.date('Ymdhis').$export_name.'_'.$page.'.xlsx';
                $send_path = $path.'/'.date('Ymdhis').$export_name.'_'.$page.'.xlsx';
            }
            $result = $writer->save($url);
            return $send_path;
    }
    /**
     * @xk 导入表格
     *
     * @method import
     * @return [type]     [description]
     * @Time   2021-09-08
     * @City   青岛
     * @Author xkyinzhe   <zhonghuaxinxing@sina.cn>
     */
    public static function import($file_path = '', $sheet = 0, $search_cell = [], $search_name = [],$start = 2){
        header("content-type:text/html;charset=utf-8");
        //载入excel文件
        $excel =  IOFactory::load($file_path, $encode = 'utf-8');
        //读取第一张表
        $sheet = $excel->getSheet($sheet);
        //获取总行数
        $row_num = $sheet->getHighestRow();
        //获取总列数
        $col_num = $sheet->getHighestColumn();
        $import_data = []; //数组形式获取表格数据
        for ($i = $start; $i <= $row_num; $i++) {
          foreach ($search_cell as $key => $value) {
            $import_data[$i][$search_name[$key]] =  (string)trim((string)$sheet->getCell($value . $i)->getValue());
          }
        }
        return $import_data;
    }
}
